﻿using BCCommon;
using BCData.Common.WebsiteConfiguration;
using BCData.WeChatComponent.WeChatMediaRecord;
using BCData.WeChatComponent.WeChatMessagePushRecord;
using BCData.WeChatComponent.WeChatMessagePushResultVerificationRecord;
using BCData.WeChatComponent.WeChatNewsMaterialArticleRecord;
using BCDto.WeChatComponent.WeChatMediaRecord;
using BCDto.WeChatComponent.WeChatMessagePushRecord;
using BCDto.WeChatComponent.WeChatMessagePushResultVerificationRecord;
using BCDto.WeChatComponent.WeChatNewsMaterialArticleRecord;
using BCDto.WeChatComponent.WeChatPushMessage;
using BCEntity.WeChatComponent.WeChatMediaRecord;
using BCEntity.WeChatComponent.WeChatMessagePushRecord;
using BCEntity.WeChatComponent.WeChatNewsMaterialArticleRecord;
using BCService.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WeChatSDK.Common.Enums.MP;
using WeChatSDK.WeChatDto.MP;
using WeChatSDK.WeChatServiceComponent.News.News;

namespace BCService.WeChatComponent.WeChatMessagePushService
{
    /// <summary>
    /// 微信群发服务
    /// </summary>
    public class WeChatMessagePushService : IWeChatMessagePushService
    {
        private readonly IWeChatMediaRecordData weChatMediaRecordData;
        private readonly IWeChatNewsMaterialArticleRecordData weChatNewsMaterialArticleRecordData;
        private readonly IWeChatMessagePushRecordData weChatMessagePushRecordData;
        private readonly IWeChatMessagePushResultVerificationRecordData weChatMessagePushResultVerificationRecordData;
        private readonly IWebsiteConfigurationData websiteConfigurationData;
        private readonly MPService mPService;


        public WeChatMessagePushService(IWeChatMediaRecordData weChatMediaRecordData,
            IWeChatNewsMaterialArticleRecordData weChatNewsMaterialArticleRecordData,
            IWeChatMessagePushRecordData weChatMessagePushRecordData,
            IWeChatMessagePushResultVerificationRecordData weChatMessagePushResultVerificationRecordData,
            IWebsiteConfigurationData websiteConfigurationData)
        {
            this.weChatMediaRecordData = weChatMediaRecordData;
            this.weChatNewsMaterialArticleRecordData = weChatNewsMaterialArticleRecordData;
            this.weChatMessagePushRecordData = weChatMessagePushRecordData;
            this.weChatMessagePushResultVerificationRecordData = weChatMessagePushResultVerificationRecordData;
            this.websiteConfigurationData = websiteConfigurationData;
            this.mPService = new MPService();
        }
        
        public void DeletePushMessage(WeChatPushMessageDeleteDto weChatPushMessageDeleteDto)
        {
            WeChatHttpResponseHandle.ProcessMessage(this.mPService.Delete(weChatPushMessageDeleteDto.MessageId, weChatPushMessageDeleteDto.ArticleIndex));
            WeChatMessagePushRecordEntity weChatMessagePushRecordEntity = this.weChatMessagePushRecordData.GetEntity(weChatPushMessageDeleteDto.MessageId);
            IEnumerable<WeChatNewsMaterialArticleRecordEntity> weChatNewsMaterialArticleRecordEntities = this.weChatNewsMaterialArticleRecordData.Get(weChatMessagePushRecordEntity.MediaId);
            if (weChatPushMessageDeleteDto.ArticleIndex.HasValue && weChatPushMessageDeleteDto.ArticleIndex.Value == 0)
            {
                this.weChatMessagePushRecordData.Delete(weChatPushMessageDeleteDto.MessageId);
                this.weChatMediaRecordData.Delete(weChatMessagePushRecordEntity.MediaId);
                this.weChatNewsMaterialArticleRecordData.Delete(weChatMessagePushRecordEntity.MediaId);
            }
            else {
                WeChatNewsMaterialArticleRecordEntity weChatNewsMaterialArticleRecordEntity = weChatNewsMaterialArticleRecordEntities.SingleOrDefault(p => p.Index == weChatPushMessageDeleteDto.ArticleIndex - 1);
                if (weChatNewsMaterialArticleRecordEntity == default(WeChatNewsMaterialArticleRecordEntity))
                {
                    throw new ArgumentException("此群发文章不存在!");
                }
                this.weChatNewsMaterialArticleRecordData.DeleteArticle(weChatNewsMaterialArticleRecordEntity.WeChatNewsMaterialArticleRecordId);
            }
        }
        public PageableList<WeChatMessagePushRecordDto> Query(string mediaId, string msgStatus, DateTime? start, DateTime? end, bool? ascending, int pageIndex = 1, int pageSize = 10)
        {
            IEnumerable<WeChatMessagePushRecordEntity> weChatMessagePushRecordEntities = this.weChatMessagePushRecordData.GetList(mediaId, msgStatus,start, end, out int dataCount, ascending, pageIndex, pageSize);
            IEnumerable<WeChatMessagePushRecordDto> list = weChatMessagePushRecordEntities.As<IEnumerable<WeChatMessagePushRecordDto>>();
            
            foreach (var item in list)
            {
                if (!string.IsNullOrWhiteSpace(item.MediaId))
                {
                    WeChatMediaRecordDto weChatMediaRecordDto = this.weChatMediaRecordData.GetEntity(item.MediaId).As<WeChatMediaRecordDto>();
                    if (weChatMediaRecordDto != null)
                    {
                        IEnumerable<WeChatNewsMaterialArticleRecordDto> weChatNewsMaterialArticleRecordDtos = this.weChatNewsMaterialArticleRecordData.Get(item.MediaId).As<IEnumerable<WeChatNewsMaterialArticleRecordDto>>();
                        //Parallel.ForEach(weChatNewsMaterialArticleRecordDtos, p =>
                        // {
                        //     p.ImageUrl = string.Concat(websiteHost, p.ImageUrl);
                        // });
                        weChatMediaRecordDto.WeChatNewsMaterialArticleRecords = weChatNewsMaterialArticleRecordDtos.Any() ? weChatNewsMaterialArticleRecordDtos : null;
                        weChatMediaRecordDto.LocalUrl = weChatMediaRecordDto.LocalUrl;
                        item.WeChatMessagePushResultVerificationRecords = this.weChatMessagePushResultVerificationRecordData.Get(item.MsgId, item.MediaId).As<IEnumerable<WeChatMessagePushResultVerificationRecordDto>>();
                        item.WeChatMediaRecord = weChatMediaRecordDto;
                    }
                }
            }
            return new PageableList<WeChatMessagePushRecordDto>
            {
                Count = dataCount,
                Items = list
            };
        }

        public string PreviewPushMessage(string mediaId, string openId, string wechatName, string content)
        {
            WeChatMediaRecordEntity weChatMediaRecordEntity = default(WeChatMediaRecordEntity);
            string type = "Text";
            if (!string.IsNullOrWhiteSpace(mediaId))
            {
                weChatMediaRecordEntity = this.weChatMediaRecordData.GetEntity(mediaId);
                type = weChatMediaRecordEntity.Type.ToString();
            }
            WeChatMPType weChatMPType = (WeChatMPType)Enum.Parse(typeof(WeChatMPType), type);
            IMPTouserPreviewConstraint mPDto;
            switch (weChatMPType)
            {
                case WeChatMPType.Card:
                    mPDto = new MPPreviewWXCardDto()
                    {
                        Msgtype = "wxcard",
                        Touser = openId,
                        Towxname = wechatName,
                        Wxcard = new MPWXCardContentDto()
                        {
                            CardId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Image:
                    mPDto = new MPPreviewImageDto()
                    {
                        Msgtype = "image",
                        Touser = openId,
                        Towxname = wechatName,
                        Image = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.News:
                    mPDto = new MPPreviewNewsDto()
                    {
                        Msgtype = "mpnews",
                        Touser = openId,
                        Towxname = wechatName,
                        Mpnews = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        },
                        SendIgnoreReprint =1
                    };
                    break;
                case WeChatMPType.Text:
                    mPDto = new MPPreviewTextDto()
                    {
                        Msgtype = "text",
                        Touser = openId,
                        Towxname = wechatName,
                        Text = new MPTextContentDto
                        {
                            Content = content
                        }
                    };
                    break;
                case WeChatMPType.Video:
                    mPDto = new MPPreviewVideoDto()
                    {
                        Msgtype = "mpvideo",
                        Touser = openId,
                        Towxname = wechatName,
                        Mpvideo = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Voice:
                    mPDto = new MPPreviewVoiceDto()
                    {
                        Msgtype = "voice",
                        Touser = openId,
                        Towxname = wechatName,
                        Voice = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                default:
                    throw new NotImplementedException("暂时未实现！");
            }
            string response = WeChatHttpResponseHandle.ProcessMessage(mPService.Preview(openId, wechatName, mPDto));
            dynamic result = JsonConvert.DeserializeObject<dynamic>(response);
            return result.msg_id;
        }

        public void PushMessage(WeChatPushMessageRequestDto weChatPushMessageRequestDto)
        {
            string mediaId = weChatPushMessageRequestDto.MediaId;
            bool isToAll = weChatPushMessageRequestDto.IsToAll;
            int? tagId = weChatPushMessageRequestDto.TagId;
            List<string> openIds = weChatPushMessageRequestDto.OpenIds;
            string content = weChatPushMessageRequestDto.Content;
            WeChatMediaRecordEntity weChatMediaRecordEntity = default(WeChatMediaRecordEntity);
            string type = "Text";
            if (!string.IsNullOrWhiteSpace(mediaId))
            {
                weChatMediaRecordEntity = this.weChatMediaRecordData.GetEntity(mediaId);
                type = weChatMediaRecordEntity.Type.ToString();
            }
            string response = string.Empty;
            WeChatMPType weChatMPType = (WeChatMPType)Enum.Parse(typeof(WeChatMPType), type);
            if (isToAll)
            {
                response = this.SendToAll(weChatMPType, weChatMediaRecordEntity, content);
            }
            else if (!isToAll && tagId.HasValue)
            {
                response = this.SendTagId(tagId.ToString(), weChatMPType, weChatMediaRecordEntity, content);
            }
            else
            {
                response = this.SendOpenIds(openIds, weChatMPType, weChatMediaRecordEntity, content);
            }
            dynamic result = JsonConvert.DeserializeObject<dynamic>(response);
            this.weChatMessagePushRecordData.Add(new WeChatMessagePushRecordEntity()
            {
                MsgId = result.msg_id,
                MediaId = mediaId,
                MsgDataId = result.msg_data_id,
                IsPreview = false,
                Content = content
            });
        }

        #region 群发数据组装
        private string SendToAll(WeChatMPType weChatMPType, WeChatMediaRecordEntity weChatMediaRecordEntity, string content)
        {
            MPDto mPDto;
            switch (weChatMPType)
            {
                case WeChatMPType.Card:
                    mPDto = new MPFilterWXCardDto()
                    {
                        Msgtype = "wxcard",
                        Filter = new MPFilterDto
                        {
                            IsToAll = true
                        },
                        Wxcard = new MPWXCardContentDto()
                        {
                            CardId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Image:
                    mPDto = new MPFilterImageDto()
                    {
                        Msgtype = "image",
                        Filter = new MPFilterDto
                        {
                            IsToAll = true
                        },
                        Image = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.News:
                    mPDto = new MPFilterNewsDto()
                    {
                        Msgtype = "mpnews",
                        Filter = new MPFilterDto
                        {
                            IsToAll = true
                        },
                        Mpnews = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        },
                        SendIgnoreReprint = 1
                    };
                    break;
                case WeChatMPType.Text:
                    mPDto = new MPFilterTextDto()
                    {
                        Msgtype = "text",
                        Filter = new MPFilterDto
                        {
                            IsToAll = true
                        },
                        Text = new MPTextContentDto
                        {
                            Content = content
                        }
                    };
                    break;
                case WeChatMPType.Video:
                    mPDto = new MPFilterVideoDto()
                    {
                        Msgtype = "mpvideo",
                        Filter = new MPFilterDto
                        {
                            IsToAll = true
                        },
                        Mpvideo = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Voice:
                    mPDto = new MPFilterVoiceDto()
                    {
                        Msgtype = "voice",
                        Filter = new MPFilterDto
                        {
                            IsToAll = true
                        },
                        Voice = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                default:
                    throw new NotImplementedException("暂时未实现！");
            }
            if (weChatMPType == WeChatMPType.Video)
            {
                return WeChatHttpResponseHandle.ProcessMessage(mPService.MPSend(mPDto, weChatMediaRecordEntity.Title, weChatMediaRecordEntity.Description));
            }

            return WeChatHttpResponseHandle.ProcessMessage(mPService.Send(mPDto));
        }

        private string SendTagId(string tagId, WeChatMPType weChatMPType, WeChatMediaRecordEntity weChatMediaRecordEntity, string content)
        {
            MPDto mPDto;
            switch (weChatMPType)
            {
                case WeChatMPType.Card:
                    mPDto = new MPFilterWXCardDto()
                    {
                        Msgtype = "wxcard",
                        Filter = new MPFilterDto
                        {
                            IsToAll = false,
                            TagId = tagId
                        },
                        Wxcard = new MPWXCardContentDto()
                        {
                            CardId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Image:
                    mPDto = new MPFilterImageDto()
                    {
                        Msgtype = "image",
                        Filter = new MPFilterDto
                        {
                            IsToAll = false,
                            TagId = tagId
                        },
                        Image = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.News:
                    mPDto = new MPFilterNewsDto()
                    {
                        Msgtype = "mpnews",
                        Filter = new MPFilterDto
                        {
                            IsToAll = false,
                            TagId = tagId
                        },
                        Mpnews = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        },
                        SendIgnoreReprint = 1
                    };
                    break;
                case WeChatMPType.Text:
                    mPDto = new MPFilterTextDto()
                    {
                        Msgtype = "text",
                        Filter = new MPFilterDto
                        {
                            IsToAll = false,
                            TagId = tagId
                        },
                        Text = new MPTextContentDto
                        {
                            Content = content
                        }
                    };
                    break;
                case WeChatMPType.Video:
                    mPDto = new MPFilterVideoDto()
                    {
                        Msgtype = "mpvideo",
                        Filter = new MPFilterDto
                        {
                            IsToAll = false,
                            TagId = tagId
                        },
                        Mpvideo = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Voice:
                    mPDto = new MPFilterVoiceDto()
                    {
                        Msgtype = "voice",
                        Filter = new MPFilterDto
                        {
                            IsToAll = false,
                            TagId = tagId
                        },
                        Voice = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                default:
                    throw new NotImplementedException("暂时未实现！");
            }
            if (weChatMPType == WeChatMPType.Video)
            {
                return WeChatHttpResponseHandle.ProcessMessage(mPService.MPSend(mPDto, weChatMediaRecordEntity.Title, weChatMediaRecordEntity.Description));
            }
            return WeChatHttpResponseHandle.ProcessMessage(mPService.Send(mPDto));
        }

        private string SendOpenIds(List<string> openIds, WeChatMPType weChatMPType, WeChatMediaRecordEntity weChatMediaRecordEntity, string content)
        {
            MPDto mPDto;
            switch (weChatMPType)
            {
                case WeChatMPType.Card:
                    mPDto = new MPOpenWXCardDto()
                    {
                        Msgtype = "wxcard",
                        Touser = openIds.ToArray(),
                        Wxcard = new MPWXCardContentDto()
                        {
                            CardId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Image:
                    mPDto = new MPOpenImageDto()
                    {
                        Msgtype = "image",
                        Touser = openIds.ToArray(),
                        Image = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.News:
                    mPDto = new MPOpenNewsDto()
                    {
                        Msgtype = "mpnews",
                        Touser = openIds.ToArray(),
                        Mpnews = new MPMediaDto()
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        },
                        SendIgnoreReprint = 1
                    };
                    break;
                case WeChatMPType.Text:
                    mPDto = new MPOpenTextDto()
                    {
                        Msgtype = "text",
                        Touser = openIds.ToArray(),
                        Text = new MPTextContentDto
                        {
                            Content = content
                        }
                    };
                    break;
                case WeChatMPType.Video:
                    mPDto = new MPOpenVideoDto()
                    {
                        Msgtype = "mpvideo",
                        Touser = openIds.ToArray(),
                        Mpvideo = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                case WeChatMPType.Voice:
                    mPDto = new MPOpenVoiceDto()
                    {
                        Msgtype = "voice",
                        Touser = openIds.ToArray(),
                        Voice = new MPMediaDto
                        {
                            MediaId = weChatMediaRecordEntity.MediaId
                        }
                    };
                    break;
                default:
                    throw new NotImplementedException("暂时未实现！");
            }
            if (weChatMPType == WeChatMPType.Video)
            {
                return WeChatHttpResponseHandle.ProcessMessage(mPService.MPSend(mPDto, weChatMediaRecordEntity.Title, weChatMediaRecordEntity.Description));
            }
            return WeChatHttpResponseHandle.ProcessMessage(mPService.Send(mPDto));
        }

        public void UpdateAlreadyPushArticleComment(string mediaId, int messageDataId, int index, bool openComment)
        {
            WeChatMessagePushRecordEntity weChatMessagePushRecordEntity = this.weChatMessagePushRecordData.GetEntity(mediaId);
            IEnumerable<WeChatNewsMaterialArticleRecordEntity> weChatNewsMaterialArticleRecordEntities = this.weChatNewsMaterialArticleRecordData.Get(mediaId);
            if (weChatMessagePushRecordEntity == null)
            {
                throw new ArgumentException("素材并不存在！");
            }
            WeChatNewsMaterialArticleRecordEntity item = weChatNewsMaterialArticleRecordEntities.SingleOrDefault(p => p.Index == index);
            if (item == default(WeChatNewsMaterialArticleRecordEntity))
            {
                throw new ArgumentException("此文章并不存在");
            }
            if (item.NeedOpenComment == (openComment ? 1 : 0))
            {
                throw new ArgumentException("文章评论状态相同，无需操作！");
            }
            item.NeedOpenComment = (openComment ? 1 : 0);
            if (openComment)
            {
                WeChatHttpResponseHandle.ProcessMessage(new MPService().OpenNeedComment(weChatMessagePushRecordEntity.MsgDataId.Value, item.Index));
            }
            else
            {
                WeChatHttpResponseHandle.ProcessMessage(new MPService().CloseNeedComment(weChatMessagePushRecordEntity.MsgDataId.Value, item.Index));
            }
            this.weChatNewsMaterialArticleRecordData.Update(item);
        }

        #endregion
    }
}
